package com.seecen.cywbackend.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seecen.cywbackend.pojo.User;
import com.seecen.cywbackend.pojo.vo.LoginUser;
import com.seecen.cywbackend.service.UserService;
import com.seecen.cywbackend.mapper.UserMapper;
import com.seecen.cywbackend.utils.JwtHelper;
import com.seecen.cywbackend.utils.MD5Util;
import com.seecen.cywbackend.utils.Result;
import com.seecen.cywbackend.utils.ResultCodeEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;

/**
* @author lenovo
* @description 针对表【t_user(用户表)】的数据库操作Service实现
* @createDate 2025-03-20 14:22:46
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{
    @Resource
    private UserMapper userMapper;
    @Resource
    private JwtHelper jwtHelper;

    @Override
    public Result getUserInfo(String token) {
        // 1 判断token是否过期
        boolean isExpiration = jwtHelper.isExpiration(token);
        if (isExpiration) {
            return Result.build(null, ResultCodeEnum.NOT_LOGIN);
        }
        // 2 没有过期 解析用户回传的token 获取 用户信息
        // 获取用户id
        Long userId = jwtHelper.getUserId(token);
        // 根据用户id 查询用户信息
        User user = userMapper.selectById(userId);
        // 将用户密码置为空 防止传给前端被解析出密码
        user.setPassword("");
        HashMap hashMap = new HashMap();
        hashMap.put("loginUser", user);
        return Result.ok(hashMap);
    }

    @Override
    public Result pwdLogin(LoginUser loginUser) {
        // 先查账号，账号存在  再匹配密码
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, loginUser.getAccount());
        User user = userMapper.selectOne(wrapper);
        //判断数据库是否存在
        if(user==null){
            LambdaQueryWrapper<User> wrapper2 = new LambdaQueryWrapper<>();
            wrapper2.eq(User::getMobile, loginUser.getAccount());
            user = userMapper.selectOne(wrapper2);
            if(user==null){
                return Result.build(null, ResultCodeEnum.ACCOUNT_ERROR);
            }
        }
        // 判断密码是否正确
        //  利用&& 的短路功能  屏蔽 密码为空的情况  好用
        //  这里将用户输入的密码进行MD5加密，然后与数据库中存储的加密后的密码
        if (!StringUtils.isEmpty(loginUser.getPassword())
                && MD5Util.encrypt(loginUser.getPassword()).equals(user.getPassword())) {
            //登录成功
            // 根据用户id 生成一个tonken
            String token = jwtHelper.createToken(user.getId());
            HashMap hashMap = new HashMap();
            hashMap.put("token", token);
            return Result.ok(hashMap);
        }
        return Result.build(null, ResultCodeEnum.PASSWORD_ERROR);
    }

    @Override
    public Result codeLogin(String phone) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getMobile, phone);
        Long count = userMapper.selectCount(wrapper);
        if(count ==0){
            //注册用户
            User user = new User();
            user.setMobile(phone);
            user.setNickname("用户"+phone);
            user.setPassword(MD5Util.encrypt("123456"));
            userMapper.insert(user);
        }
        User user = userMapper.selectOne(wrapper);
        String token = jwtHelper.createToken(user.getId());
        HashMap hashMap = new HashMap();
        hashMap.put("token", token);
        return Result.ok(hashMap);
    }

    @Override
    public Result sendCode(String phone) {
        //根据手机号随机生成一个验证码
        String code = generateVerificationCode(phone);
        System.out.println("验证码："+code);
        return Result.ok(code);
    }

    public static String generateVerificationCode(String phoneNumber) {
        try {
            // 获取当前时间戳
            long timestamp = System.currentTimeMillis();

            // 将手机号与时间戳拼接起来作为原始字符串
            String rawString = phoneNumber + timestamp;

            // 使用SHA-256算法生成哈希值
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hashBytes = md.digest(rawString.getBytes());

            // 将哈希后的字节数组转换为正整数
            long hashValue = bytesToLong(hashBytes) & Long.MAX_VALUE;

            // 转换为6位数验证码，确保始终为6位数
            String code = String.format("%06d", hashValue % 1000000);
            return code;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Failed to generate verification code", e);
        }
    }

    /**
     * 将字节数组转换为long数值。
     *
     * @param bytes 字节数组
     * @return 转换后的long数值
     */
    private static long bytesToLong(byte[] bytes) {
        long value = 0;
        for (int i = 0; i < Math.min(bytes.length, Long.BYTES); i++) {
            value |= ((long) bytes[i] & 0xffL) << (i * 8);
        }
        return value;
    }
}




